<template>
  <div class="department-container">
    <div class="app-container">

      <div class="company">
        <!-- 左侧: 组织架构 - 部门名 -->
        <div class="c-left">{{ companyInfo.name }}</div>
        <div class="c-right">
          <div class="cr-left">负责人</div>

          <!-- 右侧: 下拉菜单 - "操作"功能下拉菜单 -->
          <div class="cr-right">
            <el-dropdown>
              <span class="el-dropdown-link">
                下拉菜单<i class="el-icon-arrow-down el-icon--right" />
              </span>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item>添加子部门</el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </div>
        </div>
      </div>

      <!-- 树形结构 -->
      <div class="tree">
        <el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick">
          <div slot-scope="{ data: myData }" class="company">
            <!-- 左侧: 组织架构 - 部门名 -->
            <div class="c-left">{{ myData.name }}</div>
            <div class="c-right">
              <div class="cr-left">{{ myData.manager }}</div>
              <!-- 右侧: 下拉菜单 - "操作"功能下拉菜单 -->
              <div class="cr-right">
                <el-dropdown>
                  <span class="el-dropdown-link">
                    操作<i class="el-icon-arrow-down el-icon--right" />
                  </span>
                  <el-dropdown-menu slot="dropdown">

                    <el-dropdown-item @click.native="addChildDepartment(myData)">添加子部门</el-dropdown-item>
                    <el-dropdown-item @click.native="editDepartment(myData)">编辑部门</el-dropdown-item>
                    <!-- 如果当前菜单是一级菜单 (没有子菜单时) -->
                    <el-dropdown-item
                      v-if="!myData.children || myData.children.length === 0"
                      @click.native="handleDeleteDepartment(myData)"
                    >删除部门</el-dropdown-item>

                  </el-dropdown-menu>
                </el-dropdown>
              </div>
            </div>
          </div>
        </el-tree>
      </div>

      <!-- 对话框 组件 -->
      <el-dialog
        :title="isEdit ? '编辑部门' : '新增部门'"
        :visible.sync="dialogVisible"
        width="50%"
      >
        <!-- 引入我们自己封装的组件 updateDialog 模态框 用于添加和点击 -->
        <update-dialog
          v-if="dialogVisible"
          :is-edit="isEdit"
          :arr-list-to-child="arrListToChild"
          :current-pid="currentPid"
          :dialog-visible="dialogVisible"
          @success="handleSuccess"
          @close="dialogVisible = false"
        />
      </el-dialog>

    </div>
  </div>
</template>

<script>
import { transformToTreeList } from '@/utils/index'
import { getDepartmentListRequest, deleteDepartmentByIdRequest } from '@/api/department'
import UpdateDialog from './UpdateDialog.vue'
export default {
  components: { UpdateDialog },
  data() {
    return {
      data: [], // 初始化数据用于渲染页面
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      // 企业名称与简介
      companyInfo: {},
      // 用来父传子, 将 myData 中的 id传给子组件
      // 我们在点击父组件中对应的菜单时, 通过作用域插槽可以获取到 当前所点击的对应项的数据
      // 通过父传子, 可以将 id 传给子组件(对话框)来使用
      currentPid: '',
      // 将父组件发送请求获取到的平铺数据传递给子组件使用
      arrListToChild: [],
      // 是否为编辑
      isEdit: false,
      // 控制模态框显示隐藏
      dialogVisible: false
    }
  },
  created() {
    this.getDepartmentList() // 获取企业部门列表
  },
  methods: {
    // ^ ==================== 请求 ====================
    // 请求 - 获取企业部门列表
    async getDepartmentList() {
      try {
        const res = await getDepartmentListRequest()
        if (res.success) { // 业务代码成功时做些什么
          // this.data = res.data
          // 利用数组的 shift 方法, 删掉数组中第一项, 并且该方法有返回值, 返回值就是第一项, 可以将第一项赋值给公司信息对象
          this.companyInfo = res.data.depts.shift()
          // 将平铺数据转换为树形结构, 赋给渲染要用到的数组对象
          // 需要传递两个参数, 第一个是 所有的平铺数据, 第二个是空字符串
          this.data = transformToTreeList(res.data.depts, '')
          // console.log(this.data)
          // 将所有的平铺数据, 取出 id name pid code 赋给数组对象传给子组件
          this.arrListToChild = res.data.depts.map(item => {
            return {
              id: item.id,
              pid: item.pid,
              name: item.name,
              code: item.code
            }
          })
        } else {
          console.log('获取企业部门列表失败')
        }
      } catch (error) {
        console.log('获取企业部门列表失败', error)
      }
    },
    // 请求 - 删除部门
    async deleteDepartmentById(id) {
      try {
        const res = await deleteDepartmentByIdRequest(id)
        if (res.success) {
          this.$message.success('删除子部门成功!')
          this.getDepartmentList() // 重新渲染页面
        } else {
          this.$message.error(res.message || '删除子部门失败')
        }
      } catch (error) {
        console.log('删除部门失败', error)
      }
    },
    // ^ ==================== 事件 ====================
    // 树形结构 菜单点击事件
    handleNodeClick(data) {
    },
    // 事件 - 添加子部门按钮点击事件
    addChildDepartment(value) {
      this.dialogVisible = true
      this.isEdit = false
      // console.log(value)
      // 由于添加功能添加的是对应菜单的子部门, 而子部门的特点是, pid 与父部门的 id 相等
      // 所以这里需要将父部门的 id (由于是给当前项添加子部门, 所以要把当期项 id 作为子部门的 pid) 传给子组件
      this.currentPid = value.id // 将从作用域插槽获取到的 id 作为参数, 赋给 currentPid传给子组件
    },
    // 模态框组件操作成功, 触发事件, 重新渲染页面, 关闭模态框
    handleSuccess() {
      this.dialogVisible = false
      this.getDepartmentList()
    },
    // 事件 - 删除子部门, 接收作用域插槽传递过来的参数
    handleDeleteDepartment(value) {
      // 使用el-message 组件 根据用户的选择, 判断是否需要删除数据
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.deleteDepartmentById(value.id) // 将获取的数据的 id 作为参数传递给删除函数
      }).catch(() => {
        this.$message.info('已取消删除')
      })
    },
    // 事件 - 修改部门
    editDepartment(value) {
      this.currentPid = value.id // 赋值, 用用于父传子
      this.dialogVisible = true
      this.isEdit = true // 修改模态框状态
    }
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  .company {
    width: 100%;
    display: flex;
    // 左侧: 组织架构 - 部门名样式
    .c-left {
      flex: 1 1 80%;
      // background-color: lightgoldenrodyellow;
    }
    .c-right {
      display: flex;
      flex: 1 1 20%;
      // background-color: lightblue;
      .cr-left {
        flex: 1 1 50%;
        // background-color: skyblue;
      }
      .cr-right {
        flex: 1 1 50%;
        // background-color: pink;
      }
    }
  }
}
</style>
